/*
 * Copyright (c) gitee.com/jiandong001.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

import { ReactShadowNode } from './ReactShadowNode';
import { ViewManagerDelegate } from './ViewManagerDelegate';
import { View } from './View';
import { StateWrapper } from './StateWrapper';
import { ReactStylesDiffMap } from './ReactStylesDiffMap';
import { ThemedReactContext } from './ThemedReactContext';
import { ReactContext } from '../bridge/ReactContext';
import { NativeModule } from '../bridge/NativeModule';
import { JSResponderHandler } from './JSResponderHandler'
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

import HashMap from '@ohos.util.HashMap';
import Stack from '@ohos.util.Stack';

//export interface ReactShadowNode {}

interface BaseJavaModule extends NativeModule {

}

//@ReactPropertyHolder
export abstract class ViewManager<T extends View, C extends ReactShadowNode> implements BaseJavaModule {
    private static readonly TAG = "ViewManager";
    public readonly name = "ViewManager";

    private mRecyclableViews?: HashMap<number, Stack<T>>  = null;
    private readonly mRecyclableViewsBufferSize: number = 1024;

    public constructor() {
//      super()
    }

//    protected void setupViewRecycling() {
//        if (ReactFeatureFlags.enableViewRecycling) {
//            this.mRecyclableViews = new HashMap();
//        }
//
//    }
//
//    protected void setupViewRecycling(int bufferSize) {
//        this.mRecyclableViewsBufferSize = bufferSize;
//        this.setupViewRecycling();
//    }
//
//    @Nullable
//    private Stack<T> getRecyclableViewStack(int surfaceId) {
//        if (this.mRecyclableViews == null) {
//            return null;
//        } else {
//            if (!this.mRecyclableViews.containsKey(surfaceId)) {
//                this.mRecyclableViews.put(surfaceId, new Stack());
//            }
//
//            return (Stack)this.mRecyclableViews.get(surfaceId);
//        }
//    }

    public updateProperties(viewToUpdate: T, props: ReactStylesDiffMap): void {
//        delegate: ViewManagerDelegate<T> = this.getDelegate();
//        if (delegate != null) {
//            ViewManagerPropertyUpdater.updateProps(delegate, viewToUpdate, props);
//        } else {
//            ViewManagerPropertyUpdater.updateProps(this, viewToUpdate, props);
//        }
//
//        this.onAfterUpdateTransaction(viewToUpdate);
    }

    protected  getDelegate(): ViewManagerDelegate<T> | null {
        return null;
    }

    public createView(reactTag: number, reactContext: ThemedReactContext, props: ReactStylesDiffMap, stateWrapper: StateWrapper, jsResponderHandler?: JSResponderHandler): T {
        let view: T = this.createViewInstance(reactTag, reactContext, props, stateWrapper);
//        if (view instanceof ReactInterceptingViewGroup) {
//            ((ReactInterceptingViewGroup)view).setOnInterceptTouchEventListener(jsResponderHandler);
//        }

        return view;
    }

    public abstract getName(): string;


    public createShadowNodeInstance(context: ReactContext): C | never {
        throw new Error("ViewManager subclasses must implement createShadowNodeInstance()");
        return null;
    }

//    public abstract Class<? extends C> getShadowNodeClass();

    protected abstract createViewInstanceImpl(var1: ThemedReactContext): T;

    protected createViewInstance(reactTag: number, reactContext: ThemedReactContext, initialProps: ReactStylesDiffMap, stateWrapper: StateWrapper) {
        let view: T = null;
//        Stack<T> recyclableViews = this.getRecyclableViewStack(reactContext.getSurfaceId());
//        if (recyclableViews != null && !recyclableViews.empty()) {
//            view = this.recycleView(reactContext, (View)recyclableViews.pop());
//        } else {
            view = this.createViewInstanceImpl(reactContext);
//        }

//        view.setId(reactTag);
        this.addEventEmitters(reactContext, view);
        if (initialProps != null) {
            this.updateProperties(view, initialProps);
        }

        if (stateWrapper != null) {
            let extraData = this.updateState(view, initialProps, stateWrapper);
            if (extraData != null) {
                this.updateExtraData(view, extraData);
            }
        }
        return view;
    }

    public onDropViewInstance(view: T) {
//        Context viewContext = view.getContext();
//        if (viewContext == null) {
//            FLog.e(NAME, "onDropViewInstance: view [" + view.getId() + "] has a null context");
//        } else if (!(viewContext instanceof ThemedReactContext)) {
//            FLog.e(NAME, "onDropViewInstance: view [" + view.getId() + "] has a context that is not a ThemedReactContext: " + viewContext);
//        } else {
//            themedReactContext = (ThemedReactContext)viewContext;
//            int surfaceId = themedReactContext.getSurfaceId();
//            Stack<T> recyclableViews = this.getRecyclableViewStack(surfaceId);
//            if (recyclableViews != null && (this.mRecyclableViewsBufferSize < 0 || recyclableViews.size() < this.mRecyclableViewsBufferSize)) {
//                recyclableViews.push(this.prepareToRecycleView(themedReactContext, view));
//            }
//        }
    }

//    protected T prepareToRecycleView(@NonNull ThemedReactContext reactContext, @NonNull T view) {
//        return view;
//    }
//
//    protected T recycleView(@NonNull ThemedReactContext reactContext, @NonNull T view) {
//        return view;
//    }

    protected addEventEmitters(reactContext: ThemedReactContext, view: T): void {
    }

    protected onAfterUpdateTransaction(view: T): void {
    }

    public abstract updateExtraData(var1: T, var2: any): void;

//    /** @deprecated */
//    @Deprecated
//    public void receiveCommand(@NonNull T root, int commandId, @Nullable ReadableArray args) {
//    }

//    public void receiveCommand(@NonNull T root, String commandId, @Nullable ReadableArray args) {
//    }
//
//    @Nullable
//    public Map<String, Integer> getCommandsMap() {
//        return null;
//    }
//
//    @Nullable
//    public Map<String, Object> getExportedCustomBubblingEventTypeConstants() {
//        return null;
//    }
//
//    @Nullable
//    public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
//        return null;
//    }
//
//    @Nullable
//    public Map<String, Object> getExportedViewConstants() {
//        return null;
//    }
//
//    public Map<String, String> getNativeProps() {
//        return ViewManagerPropertyUpdater.getNativeProps(this.getClass(), this.getShadowNodeClass());
//    }


    public updateState(view: T, props: ReactStylesDiffMap, stateWrapper: StateWrapper) : any | null {
        return null;
    }

//    public long measure(Context context, ReadableMap localData, ReadableMap props, ReadableMap state, float width, YogaMeasureMode widthMode, float height, YogaMeasureMode heightMode, @Nullable float[] attachmentsPositions) {
//        return 0L;
//    }
//
//    public long measure(Context context, MapBuffer localData, MapBuffer props, @Nullable MapBuffer state, float width, YogaMeasureMode widthMode, float height, YogaMeasureMode heightMode, @Nullable float[] attachmentsPositions) {
//        return 0L;
//    }

    public setPadding(view: T, left: number, top: number, right: number, bottom: number): void {
    }

    public onSurfaceStopped(surfaceId: number): void {
//        if (this.mRecyclableViews != null) {
//            this.mRecyclableViews.remove(surfaceId);
//        }

    }

    trimMemory(): void {
//        if (this.mRecyclableViews != null) {
//            this.mRecyclableViews = new HashMap();
//        }
    }
}
